package dm.ast.pro;

import dm.ast.DmColumn;
import dm.ast.DmConstant;
import dm.ast.DmDataType;
import dm.ast.DmExpression;
import test.envset.GlobalState;

/**
 * @author scy
 * @date 2024/5/15
 */
public class DmCastFun extends DmExpression {

    public DmDataType tarType = null;
    //如果后期进行fill时，找不到合适的列，那么直接用常量填充
    public DmConstant constantValue = null;
    public DmExpression castExp = null;

    public void setCastExp(DmExpression castExp) {
        this.castExp = castExp;
    }

    public DmCastFun() {
        isCompleted = false;
        isLeaf = true;
        setComplexity();
        setTargetWidt(1);
        setTargetDept(1);
    }

    public DmExpression getCastExp() {
        return castExp;
    }

    public void setTarType(DmDataType reType) {
        this.tarType = reType;
    }

    public void setCastInfo(DmCastFun castFun) {
        this.castExp = castFun.castExp;
    }

    public Boolean Cast(DmDataType valueType, DmDataType tarType) {
        if (valueType == DmDataType.INT) {
            if (tarType == DmDataType.BINARY) {
                return true;
            } else if (tarType == DmDataType.BOOLEAN) {
                return true;
            }
        } else if (valueType == DmDataType.CHAR) {
            if (tarType == DmDataType.INT) {
                return true;
            } else if (tarType == DmDataType.CHAR) {
                return true;
            } else if (tarType == DmDataType.BINARY) {
                return true;
            } else if (tarType == DmDataType.CLOB) {
                return true;
            } else if (tarType == DmDataType.BLOB) {
                return true;
            }
        } else if (valueType == DmDataType.CLOB) {
            //字符串大对象
            if (tarType == DmDataType.BINARY) {
                return true;
            } else if (tarType == DmDataType.BLOB) {
                return true;
            }
        } else if (valueType == DmDataType.BINARY) {
            //二进制
            if (tarType == DmDataType.INT) {
                return true;
            } else if (tarType == DmDataType.CHAR) {
                return true;
            } else if (tarType == DmDataType.BINARY) {
                return true;
            } else if (tarType == DmDataType.CLOB) {
                return true;
            } else if (tarType == DmDataType.BOOLEAN) {
                return true;
            } else if (tarType == DmDataType.TIME) {
                return true;
            }
        } else if (valueType == DmDataType.BLOB) {
            //二进制大对象
            if (tarType == DmDataType.BLOB) {
                return true;
            }
        } else if (valueType == DmDataType.BOOLEAN) {
            //判断类型
            if (tarType == DmDataType.INT) {
                return true;
            } else if (tarType == DmDataType.CHAR) {
                return true;
            } else if (tarType == DmDataType.BINARY) {
                return true;
            } else if (tarType == DmDataType.BLOB) {
                return true;
            }
        } else if (valueType == DmDataType.TIME) {
            //日期、时间时区、时间戳时区
            if (tarType==DmDataType.CHAR) {
                return true;
            } else if (valueType == DmDataType.TIME) {
                    return true;
            }

        } else if (valueType == DmDataType.INTERVAL) {
            //年月（日时）时间间隔
            if (tarType==DmDataType.CHAR) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void fill(GlobalState globalState) {

        if (!isCompleted) {
            if (castExp instanceof DmCastFun) {
                tarType = reType;
                castExp.fill(globalState);
            } else if (castExp instanceof DmExpression) {
                DmExpression tmp = globalState.getRanCastCol(reType);
                if (tmp instanceof DmConstant) {
                    constantValue = (DmConstant) tmp;
                    tarType = reType;
                } else {
                    DmCastFun castFun = (DmCastFun) tmp;
                    tarType = castFun.tarType;
                    setCastInfo(castFun);
                }
            }

            isCompleted = true;
        }
    }


    @Override
    public String toSql() {
        StringBuilder sql = new StringBuilder();

        sql.append(" CAST(");
        if (castExp instanceof DmCastFun) {
            sql.append(castExp.toSql());
        } else {
            if (constantValue == null) {
                DmColumn dmColumn = (DmColumn)castExp;
                if (dmColumn.name == null) {
                    return " " + this.getClass().getSimpleName();
                }
                sql.append(dmColumn.getFullName());
            } else {
                sql.append (constantValue.toSql());
            }

        }
        sql.append(" AS " + tarType + ") ");
        return sql.toString();
    }
}
